package com.takepoints.mobile;

import java.util.ArrayList;
import java.util.List;
import java.util.Locale;

import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.Paint;
import android.graphics.Point;
import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.drawable.Drawable;
import android.location.Address;
import android.location.Geocoder;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.nfc.NfcAdapter;
import android.os.AsyncTask;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.provider.Settings;
import android.text.TextPaint;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;

import com.google.android.maps.GeoPoint;
import com.google.android.maps.ItemizedOverlay;
import com.google.android.maps.MapActivity;
import com.google.android.maps.MapController;
import com.google.android.maps.MapView;
import com.google.android.maps.MyLocationOverlay;
import com.google.android.maps.Overlay;
import com.google.android.maps.OverlayItem;

import com.takepoints.android.TPConst;
import com.takepoints.android.bo.SiteInfoPromotion;
import com.takepoints.android.services.PublicServices;
import com.takepoints.android.util.MapItemOverlay;

public class NearBy extends MapActivity {
	
	// http://ddewaele.blogspot.com/2011/05/introducing-google-places-api.html
	// http://code.google.com/p/google-api-java-client/
	
	// http://stackoverflow.com/questions/10393589/draw-route-by-getting-my-point-to-destination-point?rq=1
	// http://stackoverflow.com/questions/10928064/make-mylocationoverlay-compass-point-to-a-particular-location?rq=1
	// http://stackoverflow.com/questions/5929742/animated-drawable-mylocationoverlay?rq=1
	// http://stackoverflow.com/questions/10167819/android-geopoint-from-location-locality?rq=1
	// http://stackoverflow.com/questions/1995998/android-get-altitude-by-longitude-and-latitude
	
	// http://advback.com/android/finding-distance-between-two-points-with-google-maps-android/
	// http://stackoverflow.com/questions/6456090/android-google-map-finding-distance
	// http://stackoverflow.com/questions/5375654/how-to-implement-google-maps-search-by-address-in-android
	
	// http://stackoverflow.com/questions/5481695/how-to-enable-gps-in-android-coding?rq=1
	// http://stackoverflow.com/questions/7990267/android-check-gps-availability-on-device
	// http://stackoverflow.com/questions/5031895/how-to-check-for-the-presence-of-a-gps-sensor
	// http://stackoverflow.com/questions/2021176/how-can-i-check-the-current-status-of-the-gps-receiver
	// http://stackoverflow.com/questions/7990267/android-check-gps-availability-on-device?rq=1
	
	// http://www.vogella.com/articles/AndroidLocationAPI/article.html
	// http://stackoverflow.com/questions/5375654/how-to-implement-google-maps-search-by-address-in-android
	
	// *** ADB USB Debugging Driver ***
	// C:\\Program Files (x86)\\Android\\android-sdk\\extras\\google\\usb_driver
	
	private MapView mapView = null;
	private List<Overlay> mapOverlays = null;
	private MapController mapController = null;
	//private ZoomControls mZoom = null;

	private LocationManager locationManager = null;
	private MyLocationListener myLocationListener = null;
	private MyLocationOverlay myLocationOverlay = null;
	
	private ItemMapMarkers itemMarkers = null;
	
	private final int DEFAULT_ZOOM_NUM = 16;
	private final int MENU_MAP_ID = 0x001;
	private final int MENU_SATELLITE_ID = 0x002;
	
	private TextView infoTextView = null;
	
	private String locateType = null;
	private String latParam = null;
	private String longParam = null;

	@Override
	protected void onCreate(Bundle icicle) {
		super.onCreate(icicle);
		setContentView(R.layout.nearby);
        manageMenu(0);
		
		locationManager = (LocationManager)getSystemService(Context.LOCATION_SERVICE);
		if(!locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER)){
			Intent intent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
            startActivity(intent);
		}
        
		mapView = (MapView)findViewById(R.id.mapview);
		mapView.setSatellite(false);
		mapView.setBuiltInZoomControls(true);			// Setup Zoom/Hide Buttons
		mapOverlays = mapView.getOverlays();			// Setup Marker
		mapController = mapView.getController();
		mapController.setZoom(DEFAULT_ZOOM_NUM);
		
		myLocationListener = new MyLocationListener();
		
		myLocationOverlay = new MyLocationOverlay(this, mapView);
		mapOverlays.add(myLocationOverlay);
        
		infoTextView = (TextView) findViewById(R.id.infoTextView);
        Bundle bundle = getIntent().getExtras();
        locateType = bundle.getString(TPConst.LOCATE_TYPE);
        
        if(TPConst.LOCATE_TYPE_SPECIFIC.equals(locateType)){
        	
            latParam = bundle.getString("latParam");
            longParam = bundle.getString("longParam");
            String siteName = bundle.getString("siteName");
            
            infoTextView.setText(siteName);
            
            Double lat = Double.parseDouble(latParam) * 1E6;
	        Double lng = Double.parseDouble(longParam) * 1E6;
	        
	        GeoPoint sitePoint = new GeoPoint(lat.intValue(), lng.intValue());
	        
	        MapItemOverlay siteItemsOverlay = new MapItemOverlay(getResources().getDrawable(R.drawable.bubble));
	        
	        OverlayItem overlayitem = new OverlayItem(sitePoint, siteName, siteName);
	        siteItemsOverlay.addOverlay(overlayitem);
	        
			mapOverlays.add(siteItemsOverlay);
			
			mapController.animateTo(sitePoint);
	        
        //} else if(TPConst.LOCATE_TYPE_NEAR_BY.equals(locateType)){
        } else{
        	
        	Drawable drawable = getResources().getDrawable(R.drawable.bubble);
    		itemMarkers = new ItemMapMarkers( drawable, this );
    		
    		locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, myLocationListener);
			Location location = locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);
			if(location != null){
				popup("Searching Location ...");
				Double lat = location.getLatitude() * 1E6;
	    		Double lng = location.getLongitude() * 1E6;
		        GeoPoint curPoint = new GeoPoint(lat.intValue(), lng.intValue());
		        
				mapController.animateTo(curPoint);
			} else{
		        myLocationOverlay.runOnFirstFix(new Runnable() {
		        	public void run() {
		        		GeoPoint myPoint = myLocationOverlay.getMyLocation();
		        		Double myLatitude = myPoint.getLatitudeE6() / 1E6;
		        		Double myLongitude = myPoint.getLongitudeE6() / 1E6;
		        		
		        		Geocoder geoCoder = new Geocoder(getBaseContext(), Locale.getDefault());
				        try{
				        	List<Address> addresses = geoCoder.getFromLocation(myLatitude, myLongitude, 1);
				        	if(addresses.size() > 0){
				        		int size = addresses.get(0).getMaxAddressLineIndex();
				        		if(size > 0){
				        			String addr = "";
				        			for(int i=0; i<size; i++){
				        				if(i == 0){
						        			addr = addresses.get(0).getAddressLine(0);
				        				}
				        				if(i == 1){
						        			addr = addr + ", " + addresses.get(0).getAddressLine(1);
				        				}
				        			}
					        		infoTextView.setText( addr );
				        		}
				        	}
				        } catch(Exception e){
				        	//popup("Error : " + e.getMessage());
				        }
		        		mapController.animateTo( myPoint );
		        		
		        		new FetchSitePromotions().execute("1");
		        	}
		        });
			}
			
        }
        
        ImageView imgCurrLoc = (ImageView)findViewById(R.id.imgCurrLoc);
        imgCurrLoc.setOnClickListener(new View.OnClickListener(){
			 public void onClick(View view) {
				 mapController.animateTo(myLocationOverlay.getMyLocation());
			 }
		});
	}
	
	@Override
	protected boolean isRouteDisplayed(){
		return true;
	}
	
    @Override
    protected void onDestroy(){
    	super.onDestroy();
        if(locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER)){
        	locationManager.removeUpdates(myLocationListener);
        }
    }
    
    @Override
    protected void onPause(){
    	super.onPause();
        if(locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER)){
        	locationManager.removeUpdates(myLocationListener);
        }
        if(myLocationOverlay != null){
	        myLocationOverlay.disableCompass(); 
	        myLocationOverlay.disableMyLocation();
        }
    }
    
    @Override
    protected void onResume() {
    	super.onResume();
        if(locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER)){
			locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, myLocationListener);
		}
        if(myLocationOverlay != null){
	        myLocationOverlay.enableCompass(); 
	        myLocationOverlay.enableMyLocation();
        }
    }
/*
	public void onLocationChanged(Location loc){
		Double lat = loc.getLatitude() * 1E6;
		Double lng = loc.getLongitude() * 1E6;
		
		mapOverlays.clear();
		GeoPoint point = new GeoPoint(lat.intValue(), lng.intValue());
		
		Drawable drawable = getResources().getDrawable(R.drawable.orangeapprove);
		MapItemOverlay mapItemsOverlay = new MapItemOverlay(drawable);
		OverlayItem overlayitem = new OverlayItem(point, "My Location", "Current location.");
		mapItemsOverlay.addOverlay(overlayitem);
		mapOverlays.add(mapItemsOverlay);
		
		if(siteItemsOverlay != null){
			mapOverlays.add(siteItemsOverlay);
		}
		
		if(TPConst.LOCATE_TYPE_NEAR_BY.equals(locateType)){
			mapController.animateTo(point);
		}
	}
*/
	private class MyLocationListener implements LocationListener{
		public void onLocationChanged(Location argLocation) {
			GeoPoint myGeoPoint = new GeoPoint( (int)(argLocation.getLatitude()*1E6)
											  , (int)(argLocation.getLongitude()*1E6) );
			mapController.animateTo(myGeoPoint);
		}
		public void onProviderDisabled(String provider) {
		}
		public void onProviderEnabled(String provider) {
		}
		public void onStatusChanged(String provider, int status, Bundle extras) {
		}
	}
	
	@Override
	public boolean onCreateOptionsMenu(Menu menu){
		menu.add(1, MENU_SATELLITE_ID, 1, "Satellite");
		menu.add(1, MENU_MAP_ID, 2, "Map");
		return true;
	}
	
	public boolean onOptionsItemSelected(MenuItem item){
		switch(item.getItemId()){
			case MENU_SATELLITE_ID:
				mapView.setSatellite(true); // Set satellite view
				return true;
			case MENU_MAP_ID:
				mapView.setSatellite(false); // Set map view
				return true;
		}
		mapView.invalidate();
		return false;
	}
	
	public class ItemMapMarkers extends ItemizedOverlay {
		
		private List<OverlayItem> mOverlays = new ArrayList<OverlayItem>();
	    private Context mContext;
	    private static final int FONT_SIZE = 12;
	    private static final int TITLE_MARGIN = 3;
	    private int markerHeight = 0;
	    
	    public ItemMapMarkers(Drawable defaultMarker) {
	        super(boundCenterBottom(defaultMarker));
	        markerHeight = ((BitmapDrawable) defaultMarker).getBitmap().getHeight();
	    }
	    
	    public ItemMapMarkers(Drawable defaultMarker, Context context) {
	        this(defaultMarker);
	        mContext = context;
	    }
	    
	    public void addOverlay(OverlayItem item) {
	        mOverlays.add(item);
	        populate();
	    }
	    public void removeOverlay(OverlayItem overlay) {
	        mOverlays.remove(overlay);
	        populate();
	    }
	    public void clear()  {
	        mOverlays.clear();
	        populate();
	    }

	    @Override
	    protected OverlayItem createItem(int i) {
	        return mOverlays.get(i);
	    }
	    @Override
	    public int size() {
	        return mOverlays.size();
	    }
	    
	    @Override
	    public void draw(android.graphics.Canvas canvas, MapView mapView, boolean shadow)  {
	        super.draw(canvas, mapView, shadow);
	        for (OverlayItem item: mOverlays){
	        	GeoPoint point = item.getPoint();
	            Point markerBottomCenterCoords = new Point();
	            mapView.getProjection().toPixels(point, markerBottomCenterCoords);
	            
	            TextPaint paintText = new TextPaint();
	            Paint paintRect = new Paint();

	            Rect rect = new Rect();
	            paintText.setTextSize(FONT_SIZE);
	            paintText.getTextBounds(item.getTitle(), 0, item.getTitle().length(), rect);

	            rect.inset(-TITLE_MARGIN, -TITLE_MARGIN);
	            rect.offsetTo(markerBottomCenterCoords.x - rect.width()/2, markerBottomCenterCoords.y - markerHeight - rect.height());

	            paintText.setTextAlign(Paint.Align.CENTER);
	            paintText.setTextSize(FONT_SIZE);
	            paintText.setARGB(255, 255, 255, 255);
	            paintRect.setARGB(130, 0, 0, 0);

	            canvas.drawRoundRect( new RectF(rect), 2, 2, paintRect);
	            canvas.drawText(item.getTitle(), rect.left + rect.width() / 2,  rect.bottom - TITLE_MARGIN, paintText);
	        }
	    }
	    
	    @Override
	    protected boolean onTap(int index) {
	        OverlayItem item = mOverlays.get(index);
	        popup( item.getSnippet() );
	        return true;
	    }
	}
	
	class FetchSitePromotions extends AsyncTask<String, Void, List<SiteInfoPromotion>>{
		
        @Override
        protected void onPreExecute(){
            super.onPreExecute();
        }
        
        @Override
        protected List<SiteInfoPromotion> doInBackground(String... params){
        	int page = Integer.parseInt(params[0]);
        	List<SiteInfoPromotion> infoL = null;
        	Double lat = myLocationOverlay.getMyLocation().getLatitudeE6() / 1E6;
        	Double lng = myLocationOverlay.getMyLocation().getLongitudeE6() / 1E6;
        	if(lat > 0.00d && lng > 0.00d){
        		infoL = PublicServices.getNearByPromotions( String.valueOf(lat)
        												  , String.valueOf(lng)
        												  , 0, page);
        	}
        	return infoL;
        }
        
        @Override
        protected void onPostExecute(List<SiteInfoPromotion> result){
        	int rows = (result==null)?0:result.size();
        	for(int i=0; i<rows; i++){
        		SiteInfoPromotion pro = result.get(i);
        		
        		Double lat = Double.parseDouble(pro.getLatitude()) * 1E6;
    	        Double lng = Double.parseDouble(pro.getLongtitude()) * 1E6;
    	        GeoPoint points = new GeoPoint(lat.intValue(), lng.intValue());
    	        
        		//mapOverlays.add( new CustomLocOverlay( String.valueOf(i+1), points, pro.getSiteName() ) );
    	        itemMarkers.addOverlay( new OverlayItem(points, pro.getCustName(), pro.getSiteName() ) );
        	}
	        if(itemMarkers.size() > 0){
        		mapOverlays.add(itemMarkers);
        	}
        }
    }
	
	
	/* ==================== Utility Methods ==================== */
	
	private void popup(String msg){
    	Toast.makeText(this, msg, Toast.LENGTH_SHORT).show();
    }
	
	private void manageMenu(int indx){
		ImageView btnHome = (ImageView)findViewById(R.id.btnHome);
		ImageView btnDiscount = (ImageView)findViewById(R.id.btnDiscount);
		ImageView btnCollect = (ImageView)findViewById(R.id.btnCollect);
		ImageView btnMyReward = (ImageView)findViewById(R.id.btnMyReward);
		ImageView btnTakeIt = (ImageView)findViewById(R.id.btnTakeIt);
		
		if(indx == 1){
			btnHome.setImageResource(R.drawable.bottom12);
		} else{
			btnHome.setImageResource(R.drawable.bottom11);
			btnHome.setOnClickListener(new View.OnClickListener(){
				public void onClick(View view) {
					Intent homeInt = new Intent(view.getContext(), Takepoints.class);
					startActivityForResult(homeInt, 0);
				 }
			});
		}
		
		if(indx == 2){
			btnDiscount.setImageResource(R.drawable.bottom22);
		} else{
			btnDiscount.setImageResource(R.drawable.bottom21);
		}
		btnDiscount.setOnClickListener(new View.OnClickListener(){
			public void onClick(View view) {
				if(getSharedIntValue(TPConst.PRF_MEMBER_ID) < 1){
					confirmLoginDlg();
				} else{
					Intent intent = new Intent(view.getContext(), MyOffers.class);
					intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP);
					startActivity(intent);
				}
			 }
		});
		
		if(indx == 3){
			btnCollect.setImageResource(R.drawable.bottom32);
		} else{
			btnCollect.setImageResource(R.drawable.bottom31);
		}
		btnCollect.setOnClickListener(new View.OnClickListener(){
			public void onClick(View view) {
				if(getSharedIntValue(TPConst.PRF_MEMBER_ID) < 1){
					confirmLoginDlg();
				} else{
					Intent intent = new Intent(view.getContext(), MyCards.class);
					intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP);
					startActivity(intent);
				}
			}
		});
		
		if(indx == 4){
			btnMyReward.setImageResource(R.drawable.bottom42);
		} else{
			btnMyReward.setImageResource(R.drawable.bottom41);
		}
		btnMyReward.setOnClickListener(new View.OnClickListener(){
			public void onClick(View view) {
				if(getSharedIntValue(TPConst.PRF_MEMBER_ID) < 1){
					confirmLoginDlg();
				} else{
					Intent intent = new Intent(view.getContext(), MyRewards.class);
					intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP);
					startActivity(intent);
				}
			 }
		});
		
		if(indx == 5){
			btnTakeIt.setImageResource(R.drawable.btm_takeit_h);
		} else{
			btnTakeIt.setImageResource(R.drawable.btm_takeit);
		}
		btnTakeIt.setOnClickListener(new View.OnClickListener(){
			public void onClick(View view) {
				if(getSharedIntValue(TPConst.PRF_MEMBER_ID) < 1){
					confirmLoginDlg();
				} else{
					NfcAdapter nfcAdapter = NfcAdapter.getDefaultAdapter();
					if(nfcAdapter.isEnabled()){
						Intent intent = new Intent(view.getContext(), TakeIt.class);
						startActivityForResult(intent, 0);
					} else{
						confirmNetworkSetting();
					}
				}
			 }
		});
	}
	
	protected int getSharedIntValue(String key){
		SharedPreferences sharePref = PreferenceManager.getDefaultSharedPreferences(this);
		return sharePref.getInt(key, 0);
	}
	
	protected void confirmLoginDlg(){
		AlertDialog.Builder alertbox = new AlertDialog.Builder(this);
		alertbox.setMessage("คุณยังไม่ได้ Login !\n\nคุณต้องการที่จะ Login ใช่มั้ย ?");
		alertbox.setPositiveButton("Yes", new DialogInterface.OnClickListener() {
			public void onClick(DialogInterface dlgInf, int which) {
				gotoLoginScreen();
			}
		});
		alertbox.setNeutralButton("No", new DialogInterface.OnClickListener() {
			public void onClick(DialogInterface dlgInf, int which) {
				dlgInf.dismiss();
			}
		});
		alertbox.show();
    }
	
	final void gotoLoginScreen(){
		try{
			Intent loginInt = new Intent(this, UserLogin.class);
			loginInt.putExtra("pageSrc", "HOME_SCREEN");
			startActivityForResult(loginInt, 0);
		} catch(Exception e){
			popup(e.getMessage());
		}
	}
	
	private void confirmNetworkSetting(){
		final AlertDialog.Builder alertbox = new AlertDialog.Builder(this);
		alertbox.setMessage("NFC ถูกปิดอยู่ !\n\nคุณต้องการเปิดการใช้งาน NFC ใช่มั้ย ?");
		alertbox.setPositiveButton("Yes", new DialogInterface.OnClickListener() {
			public void onClick(DialogInterface dlgInf, int which) {
				gotoNetworkSetting();
			}
		});
		alertbox.setNeutralButton("No", new DialogInterface.OnClickListener() {
			public void onClick(DialogInterface dlgInf, int which) {
				dlgInf.dismiss();
			}
		});
		alertbox.show();
	}
    private final void gotoNetworkSetting(){
    	startActivity(new Intent(Settings.ACTION_WIRELESS_SETTINGS));
    }
	
}
